/***************************************************************************//**
 * @file GUI/MainWindow.cpp
 * @author  Marek M. Cel <marekcel@mscsim.org>
 *
 * @section LICENSE
 *
 * Copyright (C) 2013 Marek M. Cel
 *
 * This file is part of MScSim. You can redistribute and modify it under
 * the terms of GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * Further information about the GNU General Public License can also be found
 * on the world wide web at http://www.gnu.org.
 ******************************************************************************/
#ifndef MAIN_WINDOW_CPP
#define MAIN_WINDOW_CPP
#endif

////////////////////////////////////////////////////////////////////////////////

#ifdef MSCSIM_TEST
#   include <iostream>
#endif

#include <QFile>
#include <QMessageBox>
#include <QSettings>

#include <mscsim_defs.h>

#include <Utils.h>

#include <GUI/MainWindow.h>
#include <ui_MainWindow.h>

////////////////////////////////////////////////////////////////////////////////

MainWindow::MainWindow( QWidget *parent ) :
    QMainWindow ( parent ),
    m_ui ( new Ui::MainWindow ),

    m_data ( new GUI_Data() ),
    
    m_dialogConf ( 0 ),
    m_dialogHelp ( 0 ),
    m_dialogInit ( 0 ),
    m_dialogMass ( 0 ),
    m_dialogType ( 0 ),

#   ifdef MSCSIM_TEST
    m_dialogTest ( 0 ),
#   endif
    
    m_paneData ( 0 ),
    m_paneEFIS ( 0 ),
    m_paneMain ( 0 ),
    
    m_visiblePaneData ( true ),
    m_visiblePaneEFIS ( true ),
    m_visiblePaneMain ( true ),
    
    m_internalView ( true  ),
    m_externalView ( false ),

    m_fullScreen ( false )
{
    m_ui->setupUi( this );
    
    m_dialogConf = new DialogConf( this );
    m_dialogHelp = new DialogHelp( this );
    m_dialogInit = new DialogInit( this );
    m_dialogMass = new DialogMass( this );
    m_dialogType = new DialogType( this );

#   ifdef MSCSIM_TEST
    m_dialogTest = new DialogTest( this );
#   endif
    
    m_paneData = new PaneData( this );
    m_paneEFIS = new PaneEFIS( this );
    m_paneMain = new PaneMain( this );
    
    addDockWidget( Qt::RightDockWidgetArea  , m_paneData );
    addDockWidget( Qt::BottomDockWidgetArea , m_paneEFIS );
    addDockWidget( Qt::LeftDockWidgetArea   , m_paneMain );
    
    connect( m_paneMain, SIGNAL(pushInitDialogClicked()), this, SLOT(paneMain_pushInitDialogClicked()) );
    
    settingsRead();

#   ifdef MSCSIM_TEST
    std::cout << "MSCSIM_TEST" << std::endl;
    QAction *actionTestDialog = new QAction( m_ui->menuSimulation );
    actionTestDialog->setText( "TEST" );

    connect( actionTestDialog, SIGNAL(triggered()), this, SLOT(actionTestDialog_triggered()) );

    m_ui->menuSimulation->addAction( actionTestDialog );
#   endif
    
    setSideDockAreasFullHeight( true, true );
}

////////////////////////////////////////////////////////////////////////////////

MainWindow::~MainWindow()
{
    settingsWrite();
    
    if ( m_dialogConf ) delete m_dialogConf; m_dialogConf = 0;
    if ( m_dialogHelp ) delete m_dialogHelp; m_dialogHelp = 0;
    if ( m_dialogInit ) delete m_dialogInit; m_dialogInit = 0;
    if ( m_dialogMass ) delete m_dialogMass; m_dialogMass = 0;
    if ( m_dialogType ) delete m_dialogType; m_dialogType = 0;

#   ifdef MSCSIM_TEST
    if ( m_dialogTest ) delete m_dialogTest; m_dialogTest = 0;
#   endif
    
    if ( m_paneData ) delete m_paneData; m_paneData = 0;
    if ( m_paneEFIS ) delete m_paneEFIS; m_paneEFIS = 0;
    if ( m_paneMain ) delete m_paneMain; m_paneMain = 0;
    
    if ( m_ui ) delete m_ui; m_ui = 0;

    ////////////////////////////////////////
    if ( m_data ) delete m_data; m_data = 0;
    ////////////////////////////////////////
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::update( double timeStep, const GUI_DataInp &dataInp, GUI_DataOut &dataOut )
{
    m_data->dataInp = dataInp;

#   ifdef MSCSIM_TEST
    if ( m_dialogTest->isVisible() )
    {
        m_dialogTest->updateDataInp( m_data->dataInp );
        m_dialogTest->update( timeStep );
    }
#   endif

    if ( m_ui->widgetCGI->isVisible() )
    {
        m_ui->widgetCGI->update( timeStep, m_data->dataInp.cgiDataInp, m_data->dataOut.cgiDataOut );
    }

    updatePaneData();
    updatePaneEFIS();
    updatePaneMain();

#   ifdef MSCSIM_TEST
    if ( m_dialogTest->isVisible() ) m_dialogTest->updateDataOut( m_data->dataOut );
#   endif

    dataOut = m_data->dataOut;
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionAbout_triggered()
{
    QFile aboutMScHtmlFile( ":/GUI/html/about_msc.html" );

    QString aboutMScWinTitle;
    QString aboutMScInfoText;

    aboutMScWinTitle = "About MScSim";

    if ( aboutMScHtmlFile.open( QIODevice::ReadOnly ) )
    {
        aboutMScInfoText = aboutMScHtmlFile.readAll();
        aboutMScHtmlFile.close();
    }

    QMessageBox::about( this, aboutMScWinTitle, aboutMScInfoText );
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionAboutQt_triggered()
{
    QMessageBox::aboutQt( this );
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionDialogConf_triggered()
{
    m_dialogConf->show();
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionDialogEnvr_triggered() {}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionDialogInit_triggered()
{
    m_dialogInit->show();
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionDialogHelp_triggered()
{
    m_dialogHelp->show();
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionDialogMass_triggered() {}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionDialogType_triggered()
{
    m_dialogType->show();
}

////////////////////////////////////////////////////////////////////////////////

#ifdef MSCSIM_TEST
void MainWindow::actionTestDialog_triggered()
{
    m_dialogTest->show();
}
#endif

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionPaneData_triggered( bool checked )
{
    m_visiblePaneData = checked;
    m_paneData->setVisible( checked );
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionPaneEFIS_triggered( bool checked )
{
    m_visiblePaneEFIS = checked;
    m_paneEFIS->setVisible( checked );
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionPaneMain_triggered( bool checked )
{
    m_visiblePaneMain = checked;
    m_paneMain->setVisible( checked );
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionInternalView_triggered()
{
    m_internalView = true;
    m_externalView = false;

    m_ui->actionInternalView->setChecked( true  );
    m_ui->actionExternalView->setChecked( false );

    m_ui->stackedMain->setCurrentIndex( 1 );

    m_ui->widgetCGI->setCameraManipulatorInternal();
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionExternalView_triggered()
{
    m_internalView = false;
    m_externalView = true;

    m_ui->actionInternalView->setChecked( false );
    m_ui->actionExternalView->setChecked( true  );

    m_ui->stackedMain->setCurrentIndex( 1 );

    m_ui->widgetCGI->setCameraManipulatorExternal();
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionFullScreen_triggered( bool checked )
{
    m_fullScreen = checked;

    if ( m_fullScreen )
    {
        showFullScreen();
    }
    else
    {
        showNormal();
    }
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::on_actionQuit_triggered()
{
    close();
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::paneMain_pushInitDialogClicked()
{
    m_dialogInit->show();
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::paneMain_comboBoxType_currentIndexChanged() {}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::closeEvent( QCloseEvent * event )
{
    /////////////////////////////////
    QMainWindow::closeEvent( event );
    /////////////////////////////////
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::updatePaneData()
{
    if ( m_paneData->isVisible() )
    {

    }
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::updatePaneEFIS()
{
    if ( m_paneEFIS->isVisible() )
    {
        m_paneEFIS->setRoll  ( Utils::rad2deg( m_data->dataInp.flightData.rollAngle  ) );
        m_paneEFIS->setPitch ( Utils::rad2deg( m_data->dataInp.flightData.pitchAngle ) );

        m_paneEFIS->setFlightPathMarker( Utils::rad2deg( m_data->dataInp.flightData.angleOfAttack ),
                                         Utils::rad2deg( m_data->dataInp.flightData.sideslipAngle ) );

        m_paneEFIS->setSlipSkid( 0.0 );

        m_paneEFIS->setAltitude( Utils::m2ft( m_data->dataInp.flightData.altitude_asl ) );
        m_paneEFIS->setAirspeed( Utils::mps2kts( m_data->dataInp.flightData.airspeed ) );

        m_paneEFIS->setMachNo( m_data->dataInp.flightData.machNumber );

        m_paneEFIS->setHeading( Utils::rad2deg() * m_data->dataInp.flightData.heading );

        m_paneEFIS->setClimbRate( Utils::mps2fpm( m_data->dataInp.flightData.climbRate ) / 1000.0 );

        m_paneEFIS->update();
    }
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::updatePaneMain()
{
    if ( m_paneMain->isVisible() )
    {

    }
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::setSideDockAreasFullHeight( bool left, bool rght )
{
    if ( left )
    {
        setCorner( Qt::TopLeftCorner    , Qt::LeftDockWidgetArea );
        setCorner( Qt::BottomLeftCorner , Qt::LeftDockWidgetArea );
    }
    else
    {
        setCorner( Qt::TopLeftCorner    , Qt::TopDockWidgetArea    );
        setCorner( Qt::BottomLeftCorner , Qt::BottomDockWidgetArea );
    }

    if ( rght )
    {
        setCorner( Qt::TopRightCorner    , Qt::RightDockWidgetArea );
        setCorner( Qt::BottomRightCorner , Qt::RightDockWidgetArea );
    }
    else
    {
        setCorner( Qt::TopRightCorner    , Qt::TopDockWidgetArea    );
        setCorner( Qt::BottomRightCorner , Qt::BottomDockWidgetArea );
    }
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::settingsRead()
{
    QSettings settings( MSCSIM_ORG_NAME, MSCSIM_APP_NAME );
    
    settings.beginGroup( "main_window" );
    {
        restoreGeometry( settings.value( "geometry" ).toByteArray() );
        restoreState(    settings.value( "state"    ).toByteArray() );

        m_visiblePaneData = settings.value( "visible_pane_data" , 1 ).toInt();
        m_visiblePaneEFIS = settings.value( "visible_pane_efis" , 1 ).toInt();
        m_visiblePaneMain = settings.value( "visible_pane_main" , 1 ).toInt();

        m_ui->actionPaneData->setChecked( m_visiblePaneData );
        m_ui->actionPaneEFIS->setChecked( m_visiblePaneEFIS );
        m_ui->actionPaneMain->setChecked( m_visiblePaneMain );

        m_internalView = settings.value( "internal_view" , 1 ).toInt();
        m_externalView = settings.value( "external_view" , 0 ).toInt();

        if ( m_internalView || m_externalView )
        {
            m_ui->stackedMain->setCurrentIndex( 1 );

            if ( m_internalView )
            {
                m_externalView = false;
                m_ui->widgetCGI->setCameraManipulatorInternal();
            }
            else
            {
                m_ui->widgetCGI->setCameraManipulatorExternal();
            }
        }

        m_ui->actionInternalView->setChecked( m_internalView );
        m_ui->actionExternalView->setChecked( m_externalView );

        m_fullScreen = settings.value( "full_screen" , 0 ).toInt();

        m_ui->actionFullScreen->setChecked( m_fullScreen );
    }
    settings.endGroup();
}

////////////////////////////////////////////////////////////////////////////////

void MainWindow::settingsWrite()
{
    QSettings settings( MSCSIM_ORG_NAME, MSCSIM_APP_NAME );
    
    settings.beginGroup( "main_window" );
    {
        settings.setValue( "geometry" , saveGeometry() );
        settings.setValue( "state"    , saveState()    );

        settings.setValue( "visible_pane_data" , (int)m_visiblePaneData );
        settings.setValue( "visible_pane_efis" , (int)m_visiblePaneEFIS );
        settings.setValue( "visible_pane_main" , (int)m_visiblePaneMain );

        settings.setValue( "internal_view" , (int)m_internalView );
        settings.setValue( "external_view" , (int)m_externalView );

        settings.setValue( "full_screen" , (int)m_fullScreen );
    }
    settings.endGroup();
}
